use salvo::extra::jwt_auth::*;
use salvo_core::http::{Request, Response};
use std::marker::PhantomData;
use jsonwebtoken::{encode, decode, Header, Algorithm, Validation, EncodingKey,TokenData, DecodingKey};
use std::time::{Duration, SystemTime};
use chrono::prelude::*;
use serde::{Serialize, Deserialize};
use crate::extends::config::CONFIG;
use async_trait::async_trait;
//jwt验证 handler 
pub fn create_jwt_auth_handler() -> JwtHandler<Claims> {

    let jwt_auth_config =JwtConfig{
        secret :CONFIG.jwt.secret.to_owned(),
        context_token_key : Some("user_token".to_owned()),
        context_state_key : Some("user_token_auth_state".to_owned()),
        context_data_key : Some("user_token_decode_data".to_owned()),
        response_error : true,
        claims :PhantomData::<Claims>,
        //validation : Validation {leeway: 60*60 /*60秒*60 =60分钟*/, ..Default::default()},//HS256
        validation : Validation::default(),//默认 HS256 解码验证方式
        extractors : vec![Box::new(HeaderTokenExtractor::new())],//从 header分解 获取token
    };

    JwtHandler::<Claims>::new(jwt_auth_config)
}

/// 我们的声言结构型, 需要由`Serialize` 或 `Deserialize`派生

#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
    pub sub: String, //用户ID
    pub exp: usize, //过期时间
}


#[derive(Default)]
pub struct HeaderTokenExtractor;
impl HeaderTokenExtractor {
    pub fn new() -> Self {
        HeaderTokenExtractor {}
    }
}
#[async_trait]
impl JwtExtractor for HeaderTokenExtractor {
    async fn get_token(&self, req: &mut Request) -> Option<String> {
        if let Some(auth) = req.headers().get("token") {
            if let Ok(auth) = auth.to_str() {
                return Some(auth.to_string())
            }
        }
        None
    }
}